import cv2
import time
import HandTrackingModule as htm
import autopy
import numpy as np

wCam, hCam = 640, 480
frameR = 75 # Frame Reduction
smoothening = 0.08
pTime = 0
plocX, plocY = 0, 0
clocX, clocY = 0, 0
isclick = False
isPress = False

# 在初始化部分添加
fps_list = []  # 存储最近10帧的FPS值
max_fps_count = 15  # 最大存储帧数

cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
#cap = cv2.VideoCapture(0)
cap.set(3,wCam)
cap.set(4,hCam)

wScr, hScr = autopy.screen.size()

detector = htm.handDetector(detectionCon=0.7,maxHands=1)

while True:
    # 1. Find hand landmarks

    success, img = cap.read()
    img = cv2.flip(img,1)

    if success:
        img = detector.findHands(img)
        lmList, bbox = detector.findPosition(img, draw= False)
        # 2. get the tip of the index and middle fingers
        if len(lmList) != 0:
            x1, y1 = lmList[8][1:]
            x2, y2 = lmList[12][1:]

            # 3. Check Which fingers are up
            fingers = detector.fingersUp()
            # print(fingers)
            cv2.rectangle(img, (frameR, frameR - 50), (wCam - frameR, hCam - frameR -50), (255, 0, 255), 2)
            
            # 4. Only Index Finger ：Moving Mode
            if fingers[1] == 1 and fingers[2] == 0 or abs(isPress) < 20:
                # 5. Convert Coordinates
                x1 = np.clip(x1, frameR, wCam - frameR)
                y1 = np.clip(y1, frameR - 50, hCam - frameR - 50)
                x3 = np.interp(x1,(frameR, wCam - frameR), (0, wScr))
                y3 = np.interp(y1,(frameR - 50, hCam - frameR - 50), (0, hScr))

                # 6. Smoothen Values
                clocX = plocX + (x3 - plocX) * smoothening
                clocY = plocY + (y3 - plocY) * smoothening
                # 7. Move Mouse
                x3 = np.clip(clocX, 0, wScr - 1)
                y3 = np.clip(clocY, 0, hScr - 1)
                autopy.mouse.move(x3, y3)
                cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
                plocX, plocY = clocX, clocY

        
            # 8. Both Index and middle fingers are up : Clicking Mode
            if fingers[1] == 1 and fingers[2] == 1 and abs(isPress) > 50:
                # 9. Find distance between fingers
                length , img , lineInfo = detector.findDistance(8, 12, img, r = 10)
                # print(length)
                # 10. Click mouse if distance short
                if length < 30 and not isclick:
                    autopy.mouse.click()
                    isclick = True
                if length > 50:
                    isclick = False
                if isclick:
                    cv2.circle(img, (lineInfo[4], lineInfo[5]), 15, (0, 255, 0), cv2.FILLED)
            
            # 11. isPress Mode
            isPress, _, lineInfo = detector.findDistance(4, 8, img, draw= False)
            if abs(isPress) < 20:
                autopy.mouse.toggle(autopy.mouse.Button.LEFT, True)
                cv2.circle(img, (lineInfo[4], lineInfo[5]), 15, (0, 255, 0), cv2.FILLED)
            elif abs(isPress) > 50:
                autopy.mouse.toggle(autopy.mouse.Button.LEFT, False)  #释放指定鼠标键
        
        # 11. Frame Rate
        cTime = time.time()
        if cTime != pTime:  # 避免除零错误
            fps = 1/(cTime-pTime)
            fps_list.append(fps)
            
            # 只保留最近10帧的FPS值
            if len(fps_list) > max_fps_count:
                fps_list.pop(0)
            
            # 计算平均FPS
            avg_fps = sum(fps_list) / len(fps_list)
            
            # 每10帧显示一次平均FPS
            if len(fps_list) == max_fps_count:
                cv2.putText(img, f"FPS:{int(avg_fps)}", (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
        pTime = cTime

        # 12. DIsplay
        cv2.imshow("Image", img)
        if cv2.waitKey(1) == ord('q'):
            cap.release()
            cv2.destroyAllWindows()
            break